package com.atguigu.gmall.order.service.impl;

import com.atguigu.gmall.common.util.HttpClientUtil;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 用户管理service组件
 * @author : zjj
 * @date : 2021/2/5 15:12
 */

@Service
public class OrderServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderService {
    /**
     * 购物车商品最大数量
     */
    private static final long MAX_CART_SIZE = 100;
    /**
     * 订单信息管理mapper
     */
    @Autowired
    private OrderInfoMapper orderInfoMapper;
    /**
     * 订单详情管理mapper组件
     */
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    /**
     * redis 模板
     */
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 仓库调用地址
     */
    @Value("${ware.url}")
    private String wareUrl;


    @Override
    public Long saveOrderInfo(OrderInfo orderInfo) {
        // 保存数据orderInfo,orderDetail
        // orderInfo 中，没有总金额，订单状态，userId,第三方交易编号，创建时间，过期时间，订单的主题，进程状态。
        // 计算总金额赋值给OrderInfo
        // 不需要重新赋值订单明细集合，因为在页面传递过来的时候，会自动封装好了
        // 根据springmvc 对象传值的规则，自动赋值到orderInfo.orderDetailList
        orderInfo.sumTotalAmount();
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());
        // 用户Id 通过控制器获取的！
        String outTradeNo =  "ATGUIGU" + System.currentTimeMillis() + "" + new Random().nextInt(1000);
        orderInfo.setOutTradeNo(outTradeNo);
        orderInfo.setCreateTime(new Date());
        // 过期时间 1 天
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE,1);
        orderInfo.setExpireTime(calendar.getTime());
        // 订单主题：可用给个固定的字符串 或者 获取订单明细中的名称
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        StringBuffer tradeBody = new StringBuffer();
        for (OrderDetail orderDetail : orderDetailList) {
            tradeBody.append(orderDetail.getSkuName()+"");
        }
        if (tradeBody.toString().length() > MAX_CART_SIZE){
            orderInfo.setTradeBody(tradeBody.toString().substring(0,100));
        }
        orderInfo.setTradeBody(tradeBody.toString());
        // 设置进程状态
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());
        orderInfoMapper.insert(orderInfo);

        // orderDetail 没有orderId = orderInfo.id
        for (OrderDetail orderDetail : orderDetailList) {
            // 防止主键冲突! id 自动增长
            // orderInfo.getId() 之所以能获取到Id 是因为在前面先做了插入数据
            orderDetail.setOrderId(orderInfo.getId());
            // 插入数据
            orderDetailMapper.insert(orderDetail);
        }
        // 返回我们的订单id
        return orderInfo.getId();
    }

    @Override
    public String getTradeNo(String userId) {

        // 定义流水号
        String tradeNo = UUID.randomUUID().toString().replace("-","");
        // 将tradeNo 放入缓存
        // 定义缓存的key
        String tradeNoKey = "user:"+userId+":tradeCode";
        // 存储流水号
        redisTemplate.opsForValue().set(tradeNoKey,tradeNo);
        // 返回流水号
        return tradeNo;
    }

    @Override
    public Boolean checkTradeCode(String tradeCodeNo, String userId) {
        // 定义流水号在缓存的key
        String tradeNoKey = "user:"+userId+":tradeCode";
        String tradeNoRedis = (String) redisTemplate.opsForValue().get(tradeNoKey);
        // 返回比较结果
        return tradeNoRedis.equals(tradeCodeNo);
    }

    @Override
    public void deleteTradeNo(String userId) {
        // 删除缓存流水号
        // 定义流水号在缓存的key
        String tradeNoKey = "user:"+userId+":tradeCode";
        redisTemplate.delete(tradeNoKey);
    }

    @Override
    public Boolean checkStock(Long skuId, Integer skuNum) {
        // 调用库存系统的接口 http://localhost:9001/hasStock?skuId=xxx&num=xxx 远程调用
        String result = HttpClientUtil.doGet(wareUrl + "/hasStock?skuId=" + skuId + "&num=" + skuNum);
        // 返回结果
        return "1".equals(result);
    }

    @Override
    public OrderInfo getOrderInfo(Long orderId) {
        return orderInfoMapper.selectById(orderId);
    }
}
